#include "cstdio"
#include "cstring"
#include "cstdlib"
#include "math.h"
#include "iostream"
#include "../sql/parser/parse_defs.h"
#include "common/log/log.h"
#include "util/util.h"

bool cast_to_char(const Value &value, Value &casted_value){
    char str[33] = "";
    switch(value.type){
        case INTS:{
            sprintf(str, "%d", *static_cast<int *>(value.data));
            LOG_INFO("old value: %d", *static_cast<int *>(value.data));
            break;
        }
        case FLOATS:{
            //遇到float按照规则转换不能保留末尾的0，在tycast中仍是如此
            std::string num = double2string(*static_cast<float *>(value.data));
            strcpy(str, num.c_str());
            LOG_INFO("old value: %f", *static_cast<float *>(value.data));
            break;
        }
        //default had a typo defalut
        default:
            return false;
    }
    LOG_INFO("casted value: %s", str);
    value_init_string(&casted_value, str);
    // casted_value.type = CHARS, casted_value.data = str;
    return true;
}
int cast_to_int(const Value &value, Value &casted_value){
    int int_num = 0;
        switch(value.type){
        case FLOATS:{
            int_num = static_cast<int>(round(*static_cast<float*>(value.data)));
            LOG_INFO("old value: %f", *static_cast<float *>(value.data));
            break;
        }
        case CHARS:{
            int_num = atoi(static_cast<const char *>(value.data));
            LOG_INFO("old value: %s", static_cast<char *>(value.data));
            break;
        }
        default:
            return false;
    }
    LOG_INFO("casted value: %d", int_num);
    //这种方式是使用int_num在该函数内的生存周期，否则换种方式直接自己赋值则需要使用new/delete赋值与回收
    //例如: int *int_num = new int(0)
    value_init_integer(&casted_value, int_num);
    // casted_value.type = INTS, casted_value.data = int_num;
    // LOG_INFO("casted_value.data: %d", *(int *)casted_value.data);
    return true;
}
int cast_to_float(const Value &value, Value &casted_value){
        float float_num = 0.0;
        switch(value.type){
        case INTS:{
            float_num = static_cast<float>(*static_cast<int*>(value.data));
            LOG_INFO("old value: %d", *static_cast<int *>(value.data));
            break;
        }
        case CHARS:{
            float_num = atof(static_cast<const char *>(value.data));
            LOG_INFO("old value: %s", static_cast<char *>(value.data));
            break;
        }
        default:
            return false;
    }
    LOG_INFO("casted value: %f", float_num);
    value_init_float(&casted_value, float_num);
    // casted_value.type = FLOATS, casted_value.data = float_num;
    return true;
}
